<template>
  <div class="main-container-box">
    <div class="main-container-box-left">
      <div id="article">
        <div class="article-info">
          <div class="title">{{ article.data.title }}</div>
          <div class="publish-date">修改时间：{{ article.data.date }}</div>
        </div>
        <div ref="articleRef" id="article-content" v-html="article.data.content"></div>
      </div>
    </div>
    <div class="catalog-box">
      <div class="catalog">
        <div class="catalog-title">目录</div>
        <hr />
        <div class="anchor-list">
          <a
            class="anchor-list-item"
            v-for="(c, index) in catalog"
            :key="index"
            :class="{ active: activeIndex === index }"
            @click="handleAnchorClick(index)"
            :style="{ 'padding-left': 10 + c.level * 20 + 'px' }"
          >
            {{ c.label }}
          </a>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import axios from 'axios'
import { nextTick, onMounted, onBeforeUnmount, reactive, ref, watch } from 'vue'
import { useRoute } from 'vue-router'
import mark from '../hooks/useMarked'
import Debounced from '../hooks/useDebounced'
const route = useRoute()
const article: any = reactive({
  data: {
    id: '2FDCC183-4Fd2-9346-15Ff-dF1ADF83fC4d',
  },
})
type Catalog = {
  level: number
  label: string
  offsetTop: number
}
const activeIndex = ref(-1)
const articleRef = ref()
const catalog: Catalog[] = reactive([])
const createCatalog = () => {
  catalog.splice(0, catalog.length)
  let titleNodes: HTMLElement[] = articleRef.value.querySelectorAll('h2,h3')
  titleNodes.forEach((n) => {
    catalog.push({
      level: parseInt(n.tagName.charAt(1)) - 2,
      label: n.id,
      offsetTop: n.offsetTop,
    })
  })
  console.log('创建目录成功', catalog)
}
const getArticleDetail = () => {
  axios
    .get('http://47.101.129.53:8090/articles/detail', {
      params: {
        id: '2FDCC183-4Fd2-9346-15Ff-dF1ADF83fC4d',
      },
    })
    .then((res: any) => {
      if (res.data.code === 0) {
        article.data = res.data.data
        article.data.content = mark(article.data.content)
        nextTick(() => {
          createCatalog()
        })
      } else {
        console.log(res.data.message)
      }
    })
}
const handleCatalogScroll = () => {
  console.log(document.body.scrollTop)
  catalog.forEach((c) => {
    if (c.offsetTop <= document.body.scrollTop + 70) {
      activeIndex.value = catalog.indexOf(c)
    }
  })
}
const handleAnchorClick = (index: number) => {
  document.body.scrollTop = catalog[index].offsetTop - 70
  activeIndex.value = index
}
const relates: any = reactive([])
const currentPage = ref(0)
const pageSize = 10
const getRelates = () => {
  axios
    .get('http://47.101.129.53:8090/articles/relate', {
      params: {
        id: article.data.id,
        page: currentPage.value + 1,
        size: pageSize,
      },
    })
    .then((res: any) => {
      if (res.data.code === 0) {
        relates.push(...res.data.data)
        currentPage.value += 1
      }
    })
}
function scrollListener() {
  var scrollTop = document.documentElement.scrollTop || document.body.scrollTop
  var clientHeight = document.documentElement.clientHeight || document.body.clientHeight
  var scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight
}
const debounced = new Debounced()
const debouncedUse: Function = debounced.use(scrollListener, 500, true)
const func = (...args: any) => {
  debouncedUse(...args)
}
watch(
  () => route.params.id,
  () => {
    location.reload()
  }
)
onMounted(() => {
  getArticleDetail()
  getRelates()
  window.addEventListener('scroll', func, true)
  window.addEventListener('scroll', handleCatalogScroll, true)
})
onBeforeUnmount(() => {
  window.removeEventListener('scroll', func, true)
  window.removeEventListener('scroll', handleCatalogScroll, true)
})
</script>

<style lang="less" scoped>
.main-container-box {
  display: flex;
  background-color: #f4f5f5;
  justify-content: center;
  width: 100vw;
  &-left {
    width: 50%;
    margin-top: 80px;
    #article {
      background-color: white;
      padding: 20px;
      border-radius: 10px;
      .article-info {
        .title {
          font-weight: 900;
          font-size: 2rem;
          text-align: center;
        }
        .publish-date {
          text-align: center;
          margin-bottom: 20px;
          color: #a99999;
        }
      }
      #article-content {
        :deep(img) {
          max-width: 100%;
        }
      }
    }
    .relate-list {
      margin-top: 20px;
      border-radius: 10px;
      overflow: hidden;
      background-color: #fff;
      &-header {
        padding: 20px;
        font-size: 2rem;
        font-weight: 900;
        border-bottom: 1px solid #e5e6eb;
      }
    }
  }
  .catalog-box {
    position: relative;
    left: 20px;
    width: 300px;
    margin-top: 80px;
    .catalog {
      position: fixed;
      background-color: white;
      display: flex;
      flex-direction: column;
      padding: 20px;
      border-radius: 10px;
      width: 300px;
      max-height: calc(100vh - 140px);
      overflow-y: auto;
      &-title {
        font-size: 2rem;
        font-weight: 900;
      }
      .anchor-list {
        display: flex;
        flex-direction: column;
        &-item {
          text-decoration: none;
          color: black;
          height: 2rem;
          line-height: 2rem;
          white-space: nowrap;
          text-overflow: ellipsis;
          overflow: hidden;
          &:hover,
          &.active {
            cursor: pointer;
            background-color: #ecf5ff;
          }
        }
      }
    }
  }
}
</style>
